#include "stdafx.h"
void Log(char *fmt,...);

extern "C"
{
#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
#include "jversion.h"		/* for version message */

#include <ctype.h>		/* to declare isprint() */
#include "decompress.h"
/* Create the add-on message string table. */

#define JMESSAGE(code,string)	string ,

static const char * const cdjpeg_message_table[] = {
#include "cderror.h"
  NULL
};


/*
 * This list defines the known output image formats
 * (not all of which need be supported by a given version).
 * You can change the default output format by defining DEFAULT_FMT;
 * indeed, you had better do so if you undefine PPM_SUPPORTED.
 */

typedef enum {
	FMT_BMP,		/* BMP format (Windows flavor) */
	FMT_GIF,		/* GIF format */
	FMT_OS2,		/* BMP format (OS/2 flavor) */
	FMT_PPM,		/* PPM/PGM (PBMPLUS formats) */
	FMT_RLE,		/* RLE format */
	FMT_TARGA,		/* Targa format */
	FMT_TIFF		/* TIFF format */
} IMAGE_FORMATS;

#ifndef DEFAULT_FMT		/* so can override from CFLAGS in Makefile */
#define DEFAULT_FMT	FMT_PPM
#endif

static IMAGE_FORMATS requested_fmt;


/*
 * Argument-parsing code.
 * The switch parser is designed to be useful with DOS-style command line
 * syntax, ie, intermixed switches and file names, where only the switches
 * to the left of a given file name affect processing of that file.
 * The main program in this file doesn't actually use this capability...
 */


LOCAL(void)
parse_switches (j_decompress_ptr cinfo)
{
  requested_fmt = DEFAULT_FMT;	/* set default output file format */
  cinfo->err->trace_level = 0;

  /* Scan command line options, adjust parameters */

   requested_fmt = FMT_BMP;

   //cinfo->desired_number_of_colors = 256;
   //cinfo->quantize_colors = TRUE;
   //cinfo->dct_method = JDCT_IFAST;
  
   cinfo->two_pass_quantize = FALSE;
   cinfo->dither_mode = JDITHER_ORDERED;
   
     // if (! cinfo->quantize_colors) 
	cinfo->desired_number_of_colors = 216;
      cinfo->dct_method = JDCT_FASTEST;
      cinfo->do_fancy_upsampling = FALSE;
  
  
     //cinfo->out_color_space = JCS_GRAYSCALE;
}


/*
 * Marker processor for COM and interesting APPn markers.
 * This replaces the library's built-in processor, which just skips the marker.
 * We want to print out the marker as text, to the extent possible.
 * Note this code relies on a non-suspending data source.
 */

LOCAL(unsigned int)
jpeg_getc (j_decompress_ptr cinfo)
/* Read next byte */
{
	//Log("enter the jpeg_getc\n");
  struct jpeg_source_mgr * datasrc = cinfo->src;

  if (datasrc->bytes_in_buffer == 0) {
    if (! (*datasrc->fill_input_buffer) (cinfo))
      ERREXIT(cinfo, JERR_CANT_SUSPEND);
  }
  datasrc->bytes_in_buffer--;
  return GETJOCTET(*datasrc->next_input_byte++);
}


METHODDEF(boolean)
print_text_marker (j_decompress_ptr cinfo)
{
	//Log("enter the print_text_marker\n");
    INT32 length;
  unsigned int ch;
  unsigned int lastch = 0;

  length = jpeg_getc(cinfo) << 8;
  length += jpeg_getc(cinfo);
  length -= 2;			/* discount the length word itself */

   while (--length >= 0) {
    ch = jpeg_getc(cinfo);
   }
   return TRUE;
}

METHODDEF(void)
myerror_exit (j_common_ptr cinfo)
{
	 char buffer[JMSG_LENGTH_MAX];
    /* Create the message */
    (*cinfo->err->format_message) (cinfo, buffer);

    /* Display it in a message dialog box */
//    MessageBox(GetActiveWindow(), buffer, "Fatal Errorr",
//	     MB_OK | MB_ICONERROR);
	 /* Let the memory manager delete any temp files before we die */
//	jpeg_destroy(cinfo);
//	goto __fatal__error;
	//exit(0);
}

METHODDEF(void)
myoutput_message (j_common_ptr cinfo)
{
  char buffer[JMSG_LENGTH_MAX];
  return;
  /* Create the message */
  (*cinfo->err->format_message) (cinfo, buffer);

 /* Display it in a message dialog box */
//  MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
//	     MB_OK | MB_ICONERROR);
}
BOOL
decompress (PMYBUF src, PMYBUF dest)
{
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
   djpeg_dest_ptr dest_mgr = NULL;
   JDIMENSION num_scanlines;
   bmp_dest_ptr bmpdest;
			

  /* Initialize the JPEG decompression object with default error handling. */
  cinfo.err = jpeg_std_error(&jerr);
  jerr.error_exit = myerror_exit;
  jerr.output_message = myoutput_message;

  jpeg_create_decompress(&cinfo);
  /* Add some application-specific error messages (from cderror.h) */
  jerr.addon_message_table = cdjpeg_message_table;
  jerr.first_addon_message = JMSG_FIRSTADDONCODE;
  jerr.last_addon_message = JMSG_LASTADDONCODE;

  /* Insert custom marker processor for COM and APP12.
   * APP12 is used by some digital camera makers for textual info,
   * so we provide the ability to display it as text.
   * If you like, additional APPn marker types can be selected for display,
   * but don't try to override APP0 or APP14 this way (see libjpeg.doc).
   */
//  jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker);
// jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker);

   parse_switches(&cinfo);
 
 	 /* Specify data source for decompression */
   jpeg_stdio_src(&cinfo, (FILE *)(src));

  /* Read file header, set default decompression parameters */
  if(! jpeg_read_header(&cinfo, TRUE))
  {
	  jpeg_destroy_decompress(&cinfo);
	  return FALSE;
  }

  /* Adjust default decompression parameters by re-parsing the options */
   parse_switches(&cinfo);

  /* Initialize the output module now to let it override any crucial
   * option settings (for instance, GIF wants to force color quantization).
   */
    dest_mgr = jinit_write_bmp(&cinfo, FALSE);//note by suijz on 2013-4-3 
    
  	dest_mgr->output_file =(FILE *)(dest);

 //Log("		init using tdicks: %d\n", GetTickCount() - ticks);

  /* Start decompressor */
  (void) jpeg_start_decompress(&cinfo);

 //Log("		start decompress using tdicks: %d\n",  GetTickCount() - ticks);
 
  /* Process data */
  dest_mgr->buffer = (JSAMPARRAY)(dest);
  bmpdest = (bmp_dest_ptr) dest_mgr;
  dest->pads = bmpdest->pad_bytes;

  while (cinfo.output_scanline < cinfo.output_height) {
	   dest->index = (cinfo.output_height-bmpdest->cur_output_row-1)*(cinfo.output_width*3+dest->pads)+54;
      num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
					dest_mgr->buffer_height);
	bmpdest->cur_output_row++;
    //(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
  }
 dest->index = 0;
// Log("		process data using tdicks: %d\n", GetTickCount() - ticks);

  /* Finish decompression and release memory.
   * I must do it in this order because output module has allocated memory
   * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory.
   */
  (*dest_mgr->finish_output) (&cinfo, dest_mgr);
   //Log("		write output using tdicks: %d\n", GetTickCount() - ticks);
  (void) jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);
 //Log("		destory decompress using tdicks: %d\n", GetTickCount() - ticks);
 

  if(jerr.num_warnings == EXIT_SUCCESS)
	  return TRUE;
  else
	return FALSE;
__fatal__error:
   return FALSE;
}
}
